home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 722 / 722.xpi / chrome / noscript.jar / content / noscript / Thread.js < prev    next >
Text File  |  2010-02-12  |  4KB  |  141 lines

  1. var Thread = {
  2.   
  3.   hostRunning: true,
  4.   activeQueues: 0,
  5.   activeLoops: 0,
  6.   _timers: [],
  7.   
  8.   get canSpin() {
  9.     delete this.canSpin;
  10.     return this.canSpin = this.current instanceof CI.nsIEventTarget;
  11.   },
  12.   
  13.   runWithQueue: function(callback) {
  14.     var thread = this.current;
  15.     thread instanceof CI.nsIThreadInternal;
  16.     try {
  17.       this.activeQueues++;
  18.       thread.pushEventQueue(null);
  19.       return callback();
  20.     } finally {
  21.       thread.popEventQueue();
  22.       this.activeQueues--;
  23.     }
  24.   },
  25.   
  26.   spinWithQueue: function(ctrl) {
  27.     return this.runWithQueue(function() { return Thread.spin(ctrl); });
  28.   },
  29.   
  30.   spin: function(ctrl) { 
  31.     if (!this.canSpin) throw new Error("Thread: can't spin!");
  32.  
  33.     ctrl.startTime = ctrl.startTime || Date.now();
  34.     ctrl.timeout = false;
  35.     this.activeLoops++;
  36.     this._spinInternal(ctrl);
  37.     this.activeLoops--;
  38.     ctrl.elapsed = Date.now() - ctrl.startTime;
  39.     return ctrl.timeout;
  40.   },
  41.   
  42.   _spinInternal: function(ctrl) {
  43.     var t = ctrl.startTime;
  44.     var maxTime = parseInt(ctrl.maxTime)
  45.     if (maxTime) {
  46.       while(ctrl.running && this.hostRunning) {
  47.         this.yield();
  48.         if (Date.now() - t > maxTime) {
  49.           ctrl.timeout = true;
  50.           ctrl.running = false;
  51.           break;
  52.         }
  53.       }
  54.     } else while(ctrl.running && this.hostRunning) this.yield();
  55.   },
  56.   
  57.   yield: function() {
  58.     this.current.processNextEvent(true);
  59.   },
  60.   
  61.   yieldAll: function() {
  62.     var t = this.current;
  63.     while(t.hasPendingEvents()) t.processNextEvent(false);
  64.   },
  65.   
  66.   get current() {
  67.     delete this.current;
  68.     var obj = "@mozilla.org/thread-manager;1" in CC 
  69.       ? CC["@mozilla.org/thread-manager;1"].getService() 
  70.       : CC["@mozilla.org/thread;1"].createInstance(CI.nsIThread);
  71.     this.__defineGetter__("current", function() { return obj.currentThread; });
  72.     return this.current; 
  73.   },
  74.   
  75.   get currentQueue() {
  76.     delete this.currentQueue;
  77.     var eqs = null;
  78.     const CTRID = "@mozilla.org/event-queue-service;1";
  79.     if (CTRID in CC) {
  80.       const IFace = CI.nsIEventQueueService;
  81.       eqs = CC[CTRID].getService(IFace);
  82.     }
  83.     this.__defineGetter__("currentQueue", eqs
  84.       ? function() { return eqs.getSpecialEventQueue(IFace.CURRENT_THREAD_EVENT_QUEUE); }
  85.       : this.__lookupGetter__("current")
  86.     );
  87.     return this.currentQueue;  
  88.   },
  89.   
  90.   delay: function(callback, time, self, args) {
  91.     var timer = CC["@mozilla.org/timer;1"].createInstance(CI.nsITimer);
  92.     this._timers.push(timer);
  93.     timer.initWithCallback({
  94.       notify: this._delayRunner,
  95.       context: { callback: callback, args: args || [], self: self || null }
  96.     }, time || 1, 0);
  97.   },
  98.   
  99.   asap: function(callback, self, args) {
  100.     if (this.canSpin) {
  101.       this.current.dispatch({
  102.         run: function() {
  103.           callback.apply(self, args || []);
  104.         }
  105.       }, CI.nsIEventTarget.DISPATCH_NORMAL);
  106.     } else {
  107.       this.delay(callback, 0, self, args);
  108.     }
  109.   },
  110.   
  111.   basap: function(callback, self, args) { // before as soon as possible
  112.     if (!this.canSpin) {
  113.       this.asap(callback, self, args);
  114.       return;
  115.     }
  116.     var thread = this.current;
  117.     thread instanceof CI.nsIThreadInternal;
  118.     this.activeQueues++;
  119.     thread.pushEventQueue(null);
  120.     this.asap(function() {
  121.       callback.apply(self, args || []);
  122.       thread.popEventQueue();
  123.       Thread.activeQueues--;
  124.     }, self, args);
  125.   },
  126.   
  127.   
  128.   _delayRunner: function(timer) {
  129.     var ctx = this.context;
  130.     try {
  131.       ctx.callback.apply(ctx.self, ctx.args);
  132.     } finally {
  133.       this.context = null;
  134.       var tt = Thread._timers;
  135.       var pos = tt.indexOf(timer);
  136.       if (pos > -1) tt.splice(pos, 1);
  137.       timer.cancel();
  138.     }
  139.   }
  140.   
  141. }